//
//  NetworkTools.swift
//  测试-05-AFN Swift
//
//  Created by male on 15/10/15.
//  Copyright © 2015年 itheima. All rights reserved.
//

import UIKit
import AFNetworking
/// HTTP 请求方法枚举
enum HMRequestMethod: String {
    case GET = "GET"
    case POST = "POST"
}

// MARK: 网络工具
class NetworkTools: AFHTTPSessionManager {

    // MARK: - 应用程序信息
    private let appKey = "3054704282"
    private let appSecret = "b835550f60ac49cf34937cc39df1e85f"
    private let redirectUrl = "http://www.baidu.com"
    
    /// 网络请求完成回调，类似于 OC 的 typeDefine
    typealias HMRequestCallBack = (result: AnyObject?, error: NSError?)->()
    
    
    
    // 单例
    static let sharedTools: NetworkTools = {
        
        
        let tools = NetworkTools(baseURL: nil)
        
        // 设置反序列化数据格式 - 系统会自动将 OC 框架中的 NSSet 转换成 Set
        tools.responseSerializer.acceptableContentTypes?.insert("text/plain")
        
        return tools
    }()
}

// MARK: - OAuth 相关方法
extension NetworkTools {
    
    /// OAuth 授权 URL
    /// - see: [http://open.weibo.com/wiki/Oauth2/authorize](http://open.weibo.com/wiki/Oauth2/authorize)
    var oauthURL: NSURL {
        
        let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(appKey)&redirect_uri=\(redirectUrl)"
        
        return NSURL(string: urlString)!
    }
    
    /// 加载 AccessToken
    func loadAccessToken(code: String, finished: HMRequestCallBack) {
        //更改反序列化为二进制数据
//        responseSerializer = AFHTTPResponseSerializer()
        let urlString = "https://api.weibo.com/oauth2/access_token"
        
        let params = ["client_id": appKey,
            "client_secret": appSecret,
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": redirectUrl]
        
        request(.POST, URLString: urlString, parameters: params, finished: finished)
    }
}

///用户相关信息
extension NetworkTools{
    
    //接口地址
    func loadUserInfo(uid:String,finshed:HMRequestCallBack){
        
        let urlString = "https://api.weibo.com/2/users/show.json"
        var parameters = [String : AnyObject]()
        
        //拼接字典
        parameters["uid"] = uid
        tokenRequest(.GET, URLString: urlString, parameters: parameters, finished: finshed)
    }
}


///获取微博主页信息
extension NetworkTools{

    func loadStatus(since_id since_id: Int,max_id: Int, finshed:HMRequestCallBack){
        
        let urlString = "https://api.weibo.com/2/statuses/home_timeline.json"
        var parameters = [String : AnyObject]()
        if since_id > 0 {
            parameters["since_id"] = since_id
        }else if max_id > 0 {
            parameters["max_id"] = max_id
        }
        
        tokenRequest(.GET, URLString: urlString, parameters: parameters, finished: finshed)
    }
}

//发布微博
extension NetworkTools{
    
    func sendStatus(status: String,image: UIImage?,finshed:HMRequestCallBack) {
        
        // 1. 创建参数字典
        var params = [String: AnyObject]()
        
        // 2. 设置参数
        params["status"] = status
        
        // 3. 判断是否上传图片
        if image == nil {
            let urlString = "https://api.weibo.com/2/statuses/update.json"
            
            tokenRequest(.POST, URLString: urlString, parameters: params, finished: finshed)
        } else {
            params["access_token"] = UserAccountViewModel.shareModel.account?.access_token
            let urlString = "https://upload.api.weibo.com/2/statuses/upload.json"
            
            let data = UIImagePNGRepresentation(image!)
            
            uploadMessage(urlString, data: data!, name: "pic", parameters: params, finished: finshed)
        }
    }
    
    
    func sendStatus(status: String,finshed:HMRequestCallBack) {
        
        var parameters = [String : AnyObject]()
        parameters["status"] = status
       
            let urlString = "https://api.weibo.com/2/statuses/update.json"
            tokenRequest(.POST, URLString: urlString, parameters: parameters, finished: finshed)
    }
}

// MARK: - 封装 AFN 网络方法
extension NetworkTools {
    
    /// 使用带token网络请求
    ///
    /// - parameter method:     GET / POST
    /// - parameter URLString:  URLString
    /// - parameter parameters: 参数字典
    /// - parameter finished:   完成回调
    private func tokenRequest(method: HMRequestMethod, URLString: String, var parameters: [String: AnyObject]?, finished: HMRequestCallBack){
        
        //从本地中获取token的值
        guard let token = UserAccountViewModel.shareModel.account?.access_token else{
            finished(result: nil, error: NSError(domain: "missTokenError", code: -1101, userInfo: ["messge":"token字典问为空"]))
            return
        }
        if parameters == nil {
            parameters = [String : AnyObject]()
        }
        
        parameters!["access_token"] = token
        
        request(method, URLString: URLString, parameters: parameters, finished: finished)
    }
    /// 网络请求
    ///
    /// - parameter method:     GET / POST
    /// - parameter URLString:  URLString
    /// - parameter parameters: 参数字典
    /// - parameter finished:   完成回调
    private func request(method: HMRequestMethod, URLString: String, parameters: [String: AnyObject]?, finished: HMRequestCallBack) {
        
        // 定义成功回调
        let success = { (task: NSURLSessionDataTask, result: AnyObject) -> Void in
            finished(result: result, error: nil)
        }
        
        // 定义失败回调
        let failure = { (task: NSURLSessionDataTask?, error: NSError) -> Void in
            // 在开发网络应用的时候，错误不要提示给用户，但是错误一定要输出！
            print(error)
            finished(result: nil, error: error)
        }
        
        if method == HMRequestMethod.GET {
            GET(URLString, parameters: parameters, success: success, failure: failure)
        } else {
            POST(URLString, parameters: parameters, success: success, failure: failure)
        }
    }
    
    
    //上传文件
    func uploadMessage( URLString: String,data: NSData, name: String,  parameters: [String: AnyObject]?, finished: HMRequestCallBack){

        POST(URLString, parameters: parameters, constructingBodyWithBlock: { (formData) -> Void in
            
            formData.appendPartWithFileData(data, name: name, fileName: "xxx", mimeType: "application/octet-stream")
            
            }, success: { (_, result) -> Void in
                finished(result: result, error: nil)
            }) { (_, error) -> Void in
                print(error)
                finished(result: nil, error: error)
        }
    }
}
